import { useState, useEffect, Suspense, useRef, useMemo } from 'react'
import { useParams } from 'react-router-dom'
import { Canvas, useFrame, useThree } from '@react-three/fiber'
import { Stars, Text, useGLTF, PerspectiveCamera, OrbitControls } from '@react-three/drei'
import { getPublicSpace, getModelFile } from '../api'
import * as THREE from 'three'

// 生成随机位置（在球体空间内）- 更紧凑的分布
function generateRandomPosition(index, total, radius = 22) {
    const phi = Math.acos(2 * Math.random() - 1)
    const theta = 2 * Math.PI * Math.random()
    // 使用较小的最小半径，让模型更集中
    const minRadius = radius * 0.25
    const r = minRadius + (radius - minRadius) * Math.cbrt(Math.random())

    return [
        r * Math.sin(phi) * Math.cos(theta),
        r * Math.sin(phi) * Math.sin(theta),
        r * Math.cos(phi)
    ]
}

// 计算最小生成树（Prim算法）
function calculateMST(positions) {
    if (positions.length < 2) return []

    const edges = []
    const visited = new Set([0])
    const unvisited = new Set(positions.map((_, i) => i).slice(1))

    while (unvisited.size > 0) {
        let minDist = Infinity
        let minEdge = null

        visited.forEach(v => {
            unvisited.forEach(u => {
                const dist = Math.sqrt(
                    Math.pow(positions[v][0] - positions[u][0], 2) +
                    Math.pow(positions[v][1] - positions[u][1], 2) +
                    Math.pow(positions[v][2] - positions[u][2], 2)
                )
                if (dist < minDist) {
                    minDist = dist
                    minEdge = [v, u]
                }
            })
        })

        if (minEdge) {
            edges.push(minEdge)
            visited.add(minEdge[1])
            unvisited.delete(minEdge[1])
        }
    }

    return edges
}

// 粒子连线组件 - 更明显的连线
function ParticleLine({ start, end }) {
    const points = useMemo(() => {
        const particleCount = 80 // 增加粒子数量
        const particles = []
        for (let i = 0; i < particleCount; i++) {
            const t = i / particleCount
            particles.push(
                start[0] + (end[0] - start[0]) * t,
                start[1] + (end[1] - start[1]) * t,
                start[2] + (end[2] - start[2]) * t
            )
        }
        return new Float32Array(particles)
    }, [start, end])

    const particlesRef = useRef()

    useFrame(({ clock }) => {
        if (particlesRef.current) {
            const positions = particlesRef.current.geometry.attributes.position.array
            const time = clock.getElapsedTime()

            for (let i = 0; i < positions.length; i += 3) {
                const offset = Math.sin(time * 2 + i * 0.1) * 0.1
                positions[i + 1] += offset * 0.01
            }
            particlesRef.current.geometry.attributes.position.needsUpdate = true
        }
    })

    return (
        <points ref={particlesRef}>
            <bufferGeometry>
                <bufferAttribute
                    attach="attributes-position"
                    count={points.length / 3}
                    array={points}
                    itemSize={3}
                />
            </bufferGeometry>
            <pointsMaterial
                size={0.1} // 增加粒子大小
                color="#ffd700"
                transparent
                opacity={0.5} // 增加不透明度
                sizeAttenuation
            />
        </points>
    )
}

// 光晕效果 - 淡黄色，柔和渐变
function Glow({ position, color = "#ffd700", size = 2.5 }) {
    return (
        <>
            {/* 外层光晕 - 最柔和 */}
            <mesh position={position}>
                <sphereGeometry args={[size, 32, 32]} />
                <meshBasicMaterial
                    color={color}
                    transparent
                    opacity={0.08}
                    side={THREE.BackSide}
                />
            </mesh>
            {/* 中层光晕 */}
            <mesh position={position}>
                <sphereGeometry args={[size * 0.7, 32, 32]} />
                <meshBasicMaterial
                    color={color}
                    transparent
                    opacity={0.15}
                    side={THREE.BackSide}
                />
            </mesh>
            {/* 内层光晕 - 稍亮 */}
            <mesh position={position}>
                <sphereGeometry args={[size * 0.4, 32, 32]} />
                <meshBasicMaterial
                    color={color}
                    transparent
                    opacity={0.25}
                    side={THREE.BackSide}
                />
            </mesh>
            {/* 点光源增强模型亮度 */}
            <pointLight position={position} intensity={2} color={color} distance={10} decay={2} />
        </>
    )
}

// 3D模型组件 - 更大的模型和淡黄色光晕，增强亮度
function Model3D({ model, position, onClick, isSelected }) {
    const meshRef = useRef()
    const groupRef = useRef()
    const { scene } = useGLTF(model.url)
    const [distance, setDistance] = useState(0)

    // 增强模型材质的亮度
    useEffect(() => {
        if (scene) {
            scene.traverse((child) => {
                if (child.isMesh) {
                    // 增强材质的亮度
                    if (child.material) {
                        child.material.emissive = new THREE.Color(0x222222)
                        child.material.emissiveIntensity = 0.3
                        child.material.needsUpdate = true
                    }
                }
            })
        }
    }, [scene])

    useFrame(({ camera }) => {
        if (meshRef.current) {
            meshRef.current.rotation.y += 0.005

            // 计算到相机的距离
            const dist = camera.position.distanceTo(new THREE.Vector3(...position))
            setDistance(dist)
        }
    })

    const handleClick = (e) => {
        e.stopPropagation()
        onClick(model, position)
    }

    return (
        <group ref={groupRef} position={position} onClick={handleClick}>
            {/* 淡黄色光晕效果 - 柔和渐变 */}
            <Glow position={[0, 0, 0]} size={2.8} color="#ffd700" />

            {/* 模型 - 放大到3倍 */}
            <primitive
                ref={meshRef}
                object={scene.clone()}
                scale={isSelected ? 4.5 : 3}
            />

            {/* 名称标签 - 更亮 */}
            <Text
                position={[0, -4.5, 0]}
                fontSize={0.6}
                color="#ffffff"
                anchorX="center"
                anchorY="middle"
                outlineWidth={0.08}
                outlineColor="#000"
            >
                {model.name}
            </Text>

            {/* 距离指示器（仅在较远时显示） */}
            {distance > 10 && (
                <Text
                    position={[0, -5.2, 0]}
                    fontSize={0.35}
                    color="#cccccc"
                    anchorX="center"
                    anchorY="middle"
                >
                    {distance.toFixed(1)}m
                </Text>
            )}
        </group>
    )
}

// 相机控制器
function CameraController({ targetPosition, onMoveComplete, controlsRef }) {
    const { camera } = useThree()
    const [isMoving, setIsMoving] = useState(false)
    const keysPressed = useRef({})

    useEffect(() => {
        if (targetPosition) {
            setIsMoving(true)
        }
    }, [targetPosition])

    useFrame(() => {
        if (isMoving && targetPosition) {
            const target = new THREE.Vector3(...targetPosition)
            const direction = target.clone().sub(camera.position)
            const distance = direction.length()

            if (distance > 0.1) {
                camera.position.add(direction.multiplyScalar(0.05))
                // 更新 OrbitControls 的目标
                if (controlsRef.current) {
                    controlsRef.current.target.copy(new THREE.Vector3(...targetPosition).sub(direction.normalize().multiplyScalar(5)))
                }
            } else {
                setIsMoving(false)
                if (onMoveComplete) onMoveComplete()
            }
            return // 自动移动时不处理键盘输入
        }

        // 方向键控制 - 基于 OrbitControls 的目标方向
        const moveSpeed = 0.5 // 增加移动速度，更流畅
        let moved = false

        if (controlsRef.current) {
            // 计算从相机到目标的方向（前方）
            const target = controlsRef.current.target
            const forward = new THREE.Vector3().subVectors(target, camera.position).normalize()
            const right = new THREE.Vector3().crossVectors(forward, new THREE.Vector3(0, 1, 0)).normalize()

            // 前进/后退（W/S 或 上/下箭头）
            if (keysPressed.current['ArrowUp'] || keysPressed.current['w'] || keysPressed.current['W']) {
                const movement = forward.clone().multiplyScalar(moveSpeed)
                camera.position.add(movement)
                target.add(movement)
                moved = true
            }
            if (keysPressed.current['ArrowDown'] || keysPressed.current['s'] || keysPressed.current['S']) {
                const movement = forward.clone().multiplyScalar(-moveSpeed)
                camera.position.add(movement)
                target.add(movement)
                moved = true
            }

            // 左右移动（A/D 或 左/右箭头）
            if (keysPressed.current['ArrowLeft'] || keysPressed.current['a'] || keysPressed.current['A']) {
                const movement = right.clone().multiplyScalar(-moveSpeed)
                camera.position.add(movement)
                target.add(movement)
                moved = true
            }
            if (keysPressed.current['ArrowRight'] || keysPressed.current['d'] || keysPressed.current['D']) {
                const movement = right.clone().multiplyScalar(moveSpeed)
                camera.position.add(movement)
                target.add(movement)
                moved = true
            }

            // 上下移动（空格/Shift）
            if (keysPressed.current[' ']) {
                camera.position.y += moveSpeed
                target.y += moveSpeed
                moved = true
            }
            if (keysPressed.current['Shift']) {
                camera.position.y -= moveSpeed
                target.y -= moveSpeed
                moved = true
            }

            // 如果有键盘输入，禁用 OrbitControls 的阻尼以获得即时响应
            if (moved && controlsRef.current) {
                controlsRef.current.update()
            }
        }
    })

    useEffect(() => {
        const handleKeyDown = (e) => {
            keysPressed.current[e.key] = true
        }
        const handleKeyUp = (e) => {
            keysPressed.current[e.key] = false
        }

        window.addEventListener('keydown', handleKeyDown)
        window.addEventListener('keyup', handleKeyUp)

        return () => {
            window.removeEventListener('keydown', handleKeyDown)
            window.removeEventListener('keyup', handleKeyUp)
        }
    }, [])

    return null
}

function Space() {
    const { username } = useParams()
    const [spaceData, setSpaceData] = useState(null)
    const [error, setError] = useState('')
    const [selectedModel, setSelectedModel] = useState(null)
    const [cameraTarget, setCameraTarget] = useState(null)
    const [modelPositions, setModelPositions] = useState([])
    const [mstEdges, setMSTEdges] = useState([])
    const controlsRef = useRef()

    useEffect(() => {
        loadSpace()
    }, [username])

    const loadSpace = async () => {
        try {
            const res = await getPublicSpace(username)
            setSpaceData(res.data)

            // 生成随机位置
            const positions = res.data.models
                .filter(m => m.status === 'completed')
                .map((_, index, arr) => generateRandomPosition(index, arr.length))

            setModelPositions(positions)

            // 计算最小生成树
            if (positions.length > 1) {
                const edges = calculateMST(positions)
                setMSTEdges(edges)
            }
        } catch (err) {
            setError(err.response?.data?.error || '加载失败')
        }
    }

    const handleModelClick = (model, position) => {
        setSelectedModel(model)
        // 飞到模型附近（距离更近，便于观察）
        const modelPos = new THREE.Vector3(...position)
        const cameraOffset = new THREE.Vector3(0, 2, 9) // 相机偏移：稍微上方，前方9个单位
        const targetPos = modelPos.clone().add(cameraOffset)
        setCameraTarget([targetPos.x, targetPos.y, targetPos.z])
    }

    if (error) {
        return (
            <div className="min-h-screen bg-dark-900 flex items-center justify-center">
                <div className="text-center">
                    <div className="text-6xl mb-4">😢</div>
                    <h1 className="text-2xl text-gray-100 mb-4">{error}</h1>
                    <a href="/" className="btn-primary inline-block">
                        返回首页
                    </a>
                </div>
            </div>
        )
    }

    if (!spaceData) {
        return (
            <div className="min-h-screen bg-dark-900 flex items-center justify-center">
                <div className="text-center">
                    <div className="inline-block animate-spin rounded-full h-16 w-16 border-4 border-blue-600 border-t-transparent mb-4"></div>
                    <p className="text-gray-400">加载记忆宫殿中...</p>
                </div>
            </div>
        )
    }

    const completedModels = spaceData.models
        .filter(m => m.status === 'completed')
        .map((m, i) => ({ ...m, url: getModelFile(m.id), position: modelPositions[i] }))

    return (
        <div className="min-h-screen bg-dark-900 relative">
            {/* 美化的标题 */}
            <div className="absolute top-0 left-0 right-0 z-10 bg-gradient-to-b from-dark-900/90 to-transparent backdrop-blur-sm">
                <div className="max-w-7xl mx-auto px-6 py-6">
                    <h1 className="text-3xl font-bold bg-gradient-to-r from-blue-400 via-blue-500 to-blue-600 bg-clip-text text-transparent mb-2">
                        🏛️ {spaceData.username} 的记忆宫殿
                    </h1>
                    <p className="text-gray-400 text-sm">
                        <span className="inline-flex items-center gap-2">
                            <span className="w-2 h-2 bg-blue-500 rounded-full animate-pulse"></span>
                            {completedModels.length} 个模型正在展示
                        </span>
                    </p>
                </div>
            </div>

            {/* 3D Canvas */}
            <div className="w-full h-screen">
                <Canvas>
                    <PerspectiveCamera makeDefault position={[0, 0, 20]} fov={75} />
                    <color attach="background" args={['#0a0a0f']} />
                    {/* 增强环境光 */}
                    <ambientLight intensity={1.2} />
                    {/* 主光源 - 更亮 */}
                    <pointLight position={[10, 10, 10]} intensity={2} color="#ffffff" />
                    <pointLight position={[-10, -10, -10]} intensity={1.5} color="#ffffff" />
                    {/* 额外的侧光源 */}
                    <pointLight position={[0, 10, 0]} intensity={1.5} color="#ffd700" />
                    <pointLight position={[0, -10, 0]} intensity={1} color="#4a90e2" />
                    {/* 定向光增强整体亮度 */}
                    <directionalLight position={[5, 5, 5]} intensity={1.5} color="#ffffff" />
                    <Stars radius={100} depth={50} count={5000} factor={4} />

                    <CameraController
                        targetPosition={cameraTarget}
                        onMoveComplete={() => setCameraTarget(null)}
                        controlsRef={controlsRef}
                    />

                    <OrbitControls
                        ref={controlsRef}
                        enablePan={true}
                        enableZoom={true}
                        enableRotate={true}
                        minDistance={8}
                        maxDistance={50}
                        enableDamping={false}
                    />

                    <Suspense fallback={null}>
                        {/* 渲染模型 */}
                        {completedModels.map((model) => (
                            <Model3D
                                key={model.id}
                                model={model}
                                position={model.position}
                                onClick={handleModelClick}
                                isSelected={selectedModel?.id === model.id}
                            />
                        ))}

                        {/* 渲染MST连线 */}
                        {mstEdges.map((edge, idx) => (
                            <ParticleLine
                                key={idx}
                                start={modelPositions[edge[0]]}
                                end={modelPositions[edge[1]]}
                            />
                        ))}
                    </Suspense>
                </Canvas>
            </div>

            {/* 模型详情面板 */}
            {selectedModel && (
                <div className="absolute bottom-6 left-6 right-6 md:left-auto md:right-6 md:w-96 z-20">
                    <div className="card backdrop-blur-md bg-dark-800/90 border-blue-600/30">
                        <button
                            className="absolute top-4 right-4 w-8 h-8 flex items-center justify-center rounded-lg bg-dark-700 hover:bg-dark-600 text-gray-400 hover:text-white transition-colors"
                            onClick={() => setSelectedModel(null)}
                        >
                            ✕
                        </button>
                        <h2 className="text-xl font-semibold text-gray-100 mb-2 pr-8">
                            {selectedModel.name}
                        </h2>
                        <p className="text-gray-400 text-sm mb-4">
                            {selectedModel.description || '暂无描述'}
                        </p>
                        <a
                            href={getModelFile(selectedModel.id)}
                            download={`${selectedModel.name}.glb`}
                            className="btn-primary w-full text-center inline-block"
                        >
                            📥 下载模型
                        </a>
                        {selectedModel.comment_count > 0 && (
                            <p className="mt-3 text-sm text-gray-500">
                                💬 {selectedModel.comment_count} 条留言
                            </p>
                        )}
                    </div>
                </div>
            )}
        </div>
    )
}

export default Space
